package com.xjrsoft.module.base.service.impl;

import cn.hutool.core.convert.Convert;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.xjrsoft.common.allenum.DeleteMarkEnum;
import com.xjrsoft.common.allenum.LogCategoryEnum;
import com.xjrsoft.common.allenum.OperateTypeEnum;
import com.xjrsoft.common.core.VoToColumn;
import com.xjrsoft.common.page.ConventPage;
import com.xjrsoft.common.page.PageOutput;
import com.xjrsoft.common.utils.IpUtil;
import com.xjrsoft.core.secure.utils.SecureUtil;
import com.xjrsoft.core.tool.utils.*;
import com.xjrsoft.module.base.dto.GetLogPageListDto;
import com.xjrsoft.module.base.entity.XjrBaseLog;
import com.xjrsoft.module.base.mapper.XjrBaseLogMapper;
import com.xjrsoft.module.base.service.IXjrBaseLogService;
import com.xjrsoft.module.base.utils.LogUtil;
import com.xjrsoft.module.base.vo.LogPageListVo;
import com.xjrsoft.module.interfaceManager.entity.XjrInterfaceInfo;
import com.xjrsoft.module.interfaceManager.service.IXjrInterfaceInfoService;
import org.apache.commons.collections.MapUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.servlet.http.HttpServletRequest;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
 * <p>
 * 系统日志表 服务实现类
 * </p>
 *
 * @author jobob
 * @since 2020-11-11
 */
@Service
public class XjrBaseLogServiceImpl extends ServiceImpl<XjrBaseLogMapper, XjrBaseLog> implements IXjrBaseLogService {

    @Autowired
    private IXjrInterfaceInfoService xjrInterfaceInfoService;

    @Override
    public PageOutput<LogPageListVo> getLogPageList(GetLogPageListDto dto) {
        String keyword = dto.getKeyword();
        LambdaQueryWrapper<XjrBaseLog> queryWrapper = Wrappers.<XjrBaseLog>query().lambda()
                .like(StringUtil.isNotBlank(keyword), XjrBaseLog::getModule, keyword)
                .or()
                .like(StringUtil.isNotBlank(dto.getKeyword()), XjrBaseLog::getIpAddress, dto.getKeyword())
                .or()
                .like(StringUtil.isNotBlank(dto.getKeyword()), XjrBaseLog::getOperateAccount, dto.getKeyword());
        IPage<XjrBaseLog> xjrBaseLogIPage = baseMapper.selectPage(ConventPage.getPage(dto), queryWrapper
                .select(XjrBaseLog.class, x -> VoToColumn.Convert(LogPageListVo.class).contains(x.getColumn()))
                .eq(XjrBaseLog::getDeleteMark, DeleteMarkEnum.NODELETE.getCode())
                .eq(dto.getCategoryId() != 0, XjrBaseLog::getCategoryId, dto.getCategoryId())
                .between(dto.getStartTime() != null && dto.getEndTime() != null, XjrBaseLog::getOperateTime, dto.getStartTime(), dto.getEndTime())
                .orderByDesc(XjrBaseLog::getOperateTime));
        List<XjrBaseLog> records = xjrBaseLogIPage.getRecords();
        PageOutput<LogPageListVo> output = new PageOutput<>();
        output.setTotal(Convert.toInt(xjrBaseLogIPage.getTotal()));
        List<LogPageListVo> logPageListVos =new ArrayList<>();
        for (XjrBaseLog xjrBaseLog : records) {
            LogPageListVo logPageListVo = BeanUtil.copy(xjrBaseLog, LogPageListVo.class);
            logPageListVo.setExecuteResult(xjrBaseLog.getExecuteResult()==1?"成功":"失败");
            logPageListVos.add(logPageListVo);
        }
        output.setRows(logPageListVos);
        output.setTotal(Convert.toInt(xjrBaseLogIPage.getTotal()));
        return output;
    }

    @Override
    public Boolean clearLog(int type) {
        switch (type) {
            case 1:
                return baseMapper.delete(Wrappers.<XjrBaseLog>query().lambda().lt(XjrBaseLog::getOperateTime, LocalDateTime.now().minusDays(7))) > 0;
            case 2:
                return baseMapper.delete(Wrappers.<XjrBaseLog>query().lambda().lt(XjrBaseLog::getOperateTime, LocalDateTime.now().minusDays(30))) > 0;
            case 3:
                return baseMapper.delete(Wrappers.<XjrBaseLog>query().lambda().lt(XjrBaseLog::getOperateTime, LocalDateTime.now().minusDays(90))) > 0;
            case 4:
                return baseMapper.delete(Wrappers.<XjrBaseLog>query().lambda()) > 0;
        }
        return false;
    }

    @Override
    public Boolean addLog(XjrBaseLog log) {
        return this.save(log);
    }

    @Override
    public Boolean addFormLog(JSONArray jsonArray) {
        for (int i = 0; i < jsonArray.size(); i++) {
            JSONObject jsonObject = jsonArray.getJSONObject(i);
        String formName = MapUtils.getString(jsonObject, "FormName", StringPool.EMPTY);
        JSONArray apiJournal = jsonObject.getJSONArray("apiJournal");
        String nodeType = jsonObject.getString("nodeType");
        for (int j = 0; j < apiJournal.size(); j++) {
            JSONObject apiJson = apiJournal.getJSONObject(j);
            String nodeName = apiJson.getString("nodeName");
            Integer status = apiJson.getInteger("status");
            String id = apiJson.getString("id");
            String msg = apiJson.getString("msg");
            XjrInterfaceInfo xjrInterfaceInfo = xjrInterfaceInfoService.getById(id);
            String interfaceName = "";
            if (xjrInterfaceInfo != null) {
                interfaceName = xjrInterfaceInfo.getName();
            }
            XjrBaseLog log = new XjrBaseLog();
            HttpServletRequest request = WebUtil.getRequest();
            assert request != null;
            log.setCategoryId(LogCategoryEnum.FORM.getCode());
            log.setHost(request.getRemoteHost());
            String nowTimeStr = DateUtil.formatDateTime(new Date());
            log.setOperateTime(LocalDateTime.now());
            log.setIpAddress(IpUtil.getIpAddr(request));
            log.setOperateType(OperateTypeEnum.APIINVOKE.getValue());
            log.setOperateTypeId(Integer.toString(OperateTypeEnum.APIINVOKE.getCode()));
            log.setBrowser(LogUtil.getBrowser((request.getHeader("user-agent"))));
            log.setOperateAccount(SecureUtil.getUserAccount());
            log.setOperateUserId(SecureUtil.getUserId());
            if (status == 2) {
                String message = "";
                if (StringUtil.equalsIgnoreCase(nodeType, "created")) {
                    //表单初始化
                    message = "表单处理" + nowTimeStr + formName + "表单初始化开始";
                    log.setModule("表单初始化");
                } else if (StringUtil.equalsIgnoreCase(nodeType, "edit")) {
                    message = "表单处理" + nowTimeStr + formName + "表单获取表单数据开始";
                    log.setModule("获取表单数据");
                } else if (StringUtil.equalsIgnoreCase(nodeType, "submit")) {
                    message = "表单处理" + nowTimeStr + formName + "表单提交表单开始";
                    log.setModule("提交表单");
                } else if (StringUtil.equalsIgnoreCase(nodeType, "mounted")) {
                    message = "表单处理" + nowTimeStr + formName + "表单加载表单开始";
                    log.setModule("加载表单");
                }
                log.setExecuteResult(1);
                log.setDescription(message);
            } else if (status == 3) {
                String message = "";
                if (StringUtil.equalsIgnoreCase(nodeType, "created")) {
                    //表单初始化
                    message = "表单处理" + nowTimeStr + formName + "表单初始化结束";
                    log.setModule("表单初始化");
                } else if (StringUtil.equalsIgnoreCase(nodeType, "edit")) {
                    message = "表单处理" + nowTimeStr + formName + "表单获取表单数据结束";
                    log.setModule("获取表单数据");
                } else if (StringUtil.equalsIgnoreCase(nodeType, "submit")) {
                    message = "表单处理" + nowTimeStr + formName + "表单提交表单结束";
                    log.setModule("提交表单");
                } else if (StringUtil.equalsIgnoreCase(nodeType, "mounted")) {
                    message = "表单处理" + nowTimeStr + formName + "表单加载表单结束";
                    log.setModule("加载表单");
                }
                log.setExecuteResult(1);
                log.setDescription(message);
            } else if (status == 1) {
                //节点开始
                String message = "表单处理" + nowTimeStr + formName + "表单执行" + nodeName + "节点的" + interfaceName + "接口执行成功";
                log.setExecuteResult(1);
                log.setDescription(message);
                log.setModule(nodeName);
            } else if (status == 0) {
                String message = "表单处理" + nowTimeStr + formName + "表单执行" + nodeName + "节点的" + interfaceName + "接口执行失败，失败原因:" + msg;
                log.setExecuteResult(-1);
                log.setDescription(message);
                log.setModule(nodeName);
            }
            addLog(log);
        }
    }
        return true;
    }
}
